﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Xml.Linq;

namespace VelocityAdminShell.CacheOperations
{
    internal class CacheOperationsFactory
    {
        #region Consts

        private const string AttributeName = "Name";
        private const string CacheElementName = "CacheOperation";

        #endregion

        #region Members

        private XDocument _CacheOperationsXml;
        private static CacheOperationsFactory _instance = new CacheOperationsFactory();

        #endregion

        #region Properties

        public static CacheOperationsFactory Current
        {
            get
            {
                return _instance;
            }
        }

        #endregion

        #region Ctor

        private CacheOperationsFactory()
        {
            _CacheOperationsXml = CreateAllOperationsXml();
        }

        #endregion     

        #region Methods               

        public List<CacheOperation> CreateAllCacheOperations()
        {
            List<CacheOperation> result = new List<CacheOperation>();
            foreach (var operation in _CacheOperationsXml.Root.Descendants(CacheElementName))
            {
                var op = new CacheOperation();
                op.Name = operation.Attribute(AttributeName).Value;
                foreach (var parameter in operation.Descendants())
                {
                    CreateCacheOperationParameter(op, parameter);
                }

                result.Add(op);
            }
            return result;
        }

        private void CreateCacheOperationParameter(CacheOperation op, XElement parameter)
        {
            var param = new CacheOperationParameter();
            param.ParameterName = parameter.Attribute(AttributeName).Value;
            op.EnabledParameters.Add(param);
        }

        private XDocument CreateAllOperationsXml()
        {
            var operationsResName = string.Format("{0}.CacheOperations.xml", GetType().Namespace);
            var result = LoadStringResource(Assembly.GetExecutingAssembly(), operationsResName);
            return result;
        }

        private XDocument LoadStringResource(Assembly assm, string resName)
        {
            StreamReader resStream = null;
            try
            {
                //Load the resource stream from the assembly
                var stream = assm.GetManifestResourceStream(resName);
                resStream = new StreamReader(stream);

                var result = XDocument.Load(resStream);
                return result;
            }
            finally
            {
                if (resStream != null)
                {
                    resStream.Close();
                }
            }
        }

        #endregion
    }
}
